#include #include #include #include #include #include #include #include // Include your audio library #include // Firebase setup #define FIREBASE_HOST "your-project-id.firebaseio.com" // Your Firebase project #define FIREBASE_AUTH "your-firebase-auth-key" // Your Firebase API key // Pin Definitions #define DHTPIN 13 #define DHTTYPE DHT11 #define GAS_PIN 34 #define SIM800_TX 17 #define SIM800_RX 16 #define SD_CS 5 // Chip select pin for SD card #define AUDIO_PIN 23 // Pin connected to the audio output DHT dht(DHTPIN, DHTTYPE); SoftwareSerial sim800(SIM800_RX, SIM800_TX); Audio audio; // Create an Audio object // Firebase and SIM800 Setup FirebaseData fbData; String basePath = "/sensorData"; // Message and Sound Setup String incomingSMS; // SD Card setup for sound File soundFile; // Maximum number of retries for sending data to Firebase const int MAX_RETRIES = 2; // Watchdog timer configuration const int WDT_TIMEOUT = 10; // Timeout set to 10 seconds // Function prototypes void sendCommandToSIM800(String command); void checkSMSForCodes(String sms); void playSound(String soundFileName); void sendDataToFirebase(float temp, float hum, int gas, int AQI, String collectedTime, String sentTime); String getISOTime(); int calculateAQI(int gasValue); void playAlertAudio(); void playDisasterAudio(String code); void rebootSystem(); void fullSystemScan(); void emergencyReboot(); void initSIM800(); bool isPlaying = false; // To track if audio is currently playing void setup() { Serial.begin(115200); sim800.begin(9600); esp_task_wdt_init(WDT_TIMEOUT, true); esp_task_wdt_add(NULL); // Initialize DHT sensor dht.begin(); // Initialize SD card if (!SD.begin(SD_CS)) { Serial.println("SD card initialization failed"); return; } audio.setPin(AUDIO_PIN); // Set the pin for audio output Serial.println("SD card initialized successfully"); // Firebase initialization Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH); Firebase.reconnectWiFi(true); // SIM800 initialization initSIM800(); // Initialize the SIM module } void loop() { static unsigned long lastSendTime = 0; static int retryCount = 0; esp_task_wdt_reset(); // Reset the watchdog timer // Check for incoming SMS if (sim800.available()) { incomingSMS = sim800.readString(); checkSMSForCodes(incomingSMS); } // Read sensors float temp = dht.readTemperature(); float hum = dht.readHumidity(); int gasValue = analogRead(GAS_PIN); // Calculate Air Quality Index (dummy logic for now) int AQI = calculateAQI(gasValue); // Get timestamps String dataCollected = getISOTime(); String dataSent = getISOTime(); // Assume data is sent right after collection // Send data to Firebase with retries bool dataSentSuccessfully = sendDataToFirebase(temp, hum, gasValue, AQI, dataCollected, dataSent); if (!dataSentSuccessfully) { retryCount++; if (retryCount <= MAX_RETRIES) { Serial.println("Retrying to send data..."); delay(5000); // Wait before retrying sendDataToFirebase(temp, hum, gasValue, AQI, dataCollected, dataSent); // Retry sending data } else { Serial.println("Data send failed after retries. Performing full system scan and reboot."); fullSystemScan(); // Perform full system scan rebootSystem(); // Reboot the system } } else { retryCount = 0; // Reset retry count on successful send } // Check if audio is playing if (!isPlaying) { playAlertAudio(); // Play the alert audio first } delay(10000); // Delay 10 seconds between readings } void initSIM800() { sendCommandToSIM800("AT"); delay(1000); sendCommandToSIM800("AT+CMGF=1"); // Set SMS text mode delay(1000); sendCommandToSIM800("AT+CNMI=1,2,0,0,0"); // Immediate SMS notification delay(1000); } void sendCommandToSIM800(String command) { sim800.println(command); delay(1000); while (sim800.available()) { Serial.println(sim800.readString()); } } void checkSMSForCodes(String sms) { // Split incoming SMS codes using comma as a delimiter int startIndex = 0; int endIndex; while ((endIndex = sms.indexOf(',', startIndex)) != -1) { String code = sms.substring(startIndex, endIndex); playDisasterAudio(code); // Play audio for the disaster code startIndex = endIndex + 1; } // Check the last code after the last comma if (startIndex < sms.length()) { playDisasterAudio(sms.substring(startIndex)); // Play audio for the last code } } void playSound(String soundFileName) { soundFile = SD.open(soundFileName); if (soundFile) { // Play sound logic (send data to speaker) Serial.println("Playing: " + soundFileName); soundFile.close(); } else { Serial.println("Failed to open sound file: " + soundFileName); } } bool sendDataToFirebase(float temp, float hum, int gas, int AQI, String collectedTime, String sentTime) { FirebaseJson json; json.set("sensorData/temperature", temp); json.set("sensorData/humidity", hum); json.set("sensorData/gasReadings/CO2", gas); json.set("sensorData/gasReadings/CO", gas * 0.05); // Example conversion json.set("sensorData/gasReadings/NH3", gas * 0.03); json.set("sensorData/gasReadings/NOx", gas * 0.02); json.set("sensorData/gasReadings/benzene", gas * 0.01); json.set("sensorData/airQualityIndex", AQI); json.set("timestamps/dataCollected", collectedTime); json.set("timestamps/dataSent", sentTime); json.set("status", "active"); if (Firebase.pushJSON(fbData, basePath, json)) { Serial.println("Data sent to Firebase"); return true; // Data sent successfully } else { Serial.println("Failed to send data: " + fbData.errorReason()); return false; // Data send failed } } String getISOTime() { struct tm timeinfo; if (!getLocalTime(&timeinfo)) { Serial.println("Failed to obtain time"); return ""; } char buffer[30]; strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%SZ", &timeinfo); return String(buffer); } int calculateAQI(int gasValue) { // Simple AQI calculation (example logic) return map(gasValue, 0, 1023, 0, 500); } void playAlertAudio() { String alertFilePath = "/disaster/Alert.wav"; // Path to the alert audio file if (SD.exists(alertFilePath)) { if (!audio.isPlaying()) { // Only play if not already playing audio.play(alertFilePath); // Play alert audio isPlaying = true; // Set the playing status to true Serial.println("Playing alert audio: " + alertFilePath); } } else { Serial.println("Alert audio file not found: " + alertFilePath); } } void playDisasterAudio(String code) { String soundFilePath = "/disaster/" + code + ".wav"; // Assuming files are named according to the code if (SD.exists(soundFilePath)) { audio.play(soundFilePath); isPlaying = true; // Set the playing status to true Serial.println("Playing disaster audio: " + soundFilePath); } else { Serial.println("Disaster audio file not found: " + soundFilePath); } } void rebootSystem() { Serial.println("Rebooting system..."); ESP.restart(); // Restart the ESP32 } void fullSystemScan() { Serial.println("Performing full system scan..."); // Implement full system scan logic here (if applicable) } void emergencyReboot() { Serial.println("Emergency reboot triggered."); rebootSystem(); // Reboot the system }